{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "60d8f9dc",
   "metadata": {},
   "source": [
    "## 手写数字识别"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d7c182c",
   "metadata": {},
   "source": [
    "深度学习入门案例，MNIST数据集是由Yann LeCun等人从制作出来的数据集，该数据集开始被多数人研究。\n",
    "现在常用的办法是用卷积神经网络。选择从手写数字识别开始，可以快速的理解深度学习理念和知识。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "758d09f6",
   "metadata": {},
   "source": [
    "### 数据预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f72709e3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import paddle\n",
    "from paddle.nn import Linear\n",
    "import paddle.nn.functional as F\n",
    "import os\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6d2bc0a5",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\admin\\anaconda3\\lib\\site-packages\\ipykernel\\ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
      "  and should_run_async(code)\n"
     ]
    }
   ],
   "source": [
    "train_data = paddle.vision.datasets.MNIST(mode=\"train\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "9a0ae2ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data0 = np.array(train_data[0][0])\n",
    "train_label0 = np.array(train_data[0][1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "eb628d56",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制图案\n",
    "plt.figure(\"Image\",figsize=(2,2))\n",
    "plt.imshow(train_data0,cmap=plt.cm.binary)\n",
    "plt.axis('on')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07c90c82",
   "metadata": {},
   "source": [
    "### 模型设计"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82c4f6be",
   "metadata": {},
   "source": [
    "先用一个简单但没用的模型一步一步了解深度学习的优化与知识"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "1fb7710c",
   "metadata": {},
   "outputs": [],
   "source": [
    "class MNIST(paddle.nn.Layer):\n",
    "    def __init__(self):\n",
    "        super(MNIST,self).__init__()\n",
    "        \n",
    "        # 定义一层全连接层，输入 784，输出1\n",
    "        self.fc = paddle.nn.Linear(in_features=784,out_features=1)\n",
    "    \n",
    "    def forward(self,inputs):\n",
    "        return self.fc(inputs)\n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf5d7fac",
   "metadata": {},
   "source": [
    "### 训练配置\n",
    "- 训练配置和训练过程，需要分开，对于简单的场景，可以合并"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4d0caa8c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# minst = MNIST()\n",
    "\n",
    "# def train(model):\n",
    "#     # 启动训练模式\n",
    "#     model.train()\n",
    "#     # 加载数据集\n",
    "#     train_loader = paddle.io.DataLoader(dataset=train_data,batch_size=16,shuffle=True)\n",
    "#     # 定义模型的优化器\n",
    "#     opt = paddle.optimizer.SGD(learning_rate=0.001,parameters=model.parameters())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dfb0bf0c",
   "metadata": {},
   "source": [
    "### 训练过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "00e4dd38",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 图像归一化处理\n",
    "def norm_img(img):\n",
    "    assert len(img.shape)==3\n",
    "    batch_size,img_h,img_w = img.shape\n",
    "    img = img/255\n",
    "    img = paddle.reshape(img,[batch_size,img_h*img_w])\n",
    "    return img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "dcf44bf1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# paddle.vision.set_image_backend(\"cv2\")\n",
    "\n",
    "\n",
    "def train(model):\n",
    "    model.train()\n",
    "    train_loader = paddle.io.DataLoader(dataset=train_data,batch_size=16,shuffle=True)\n",
    "    opt = paddle.optimizer.SGD(learning_rate=0.01,parameters=model.parameters())\n",
    "    EPOCH_NUM = 10\n",
    "    for epoch in range(EPOCH_NUM):\n",
    "        for batch_id,data in enumerate(train_loader()):\n",
    "            images = norm_img(data[0].astype('float32'))\n",
    "            labels = data[1].astype(\"float32\")\n",
    "            # 前向计算\n",
    "            predicts = model(images)\n",
    "            # 计算损失\n",
    "            loss = F.square_error_cost(predicts,labels)\n",
    "            avg_loss = paddle.mean(loss)\n",
    "            \n",
    "            if batch_id % 100 == 0:\n",
    "                print(\"loss:{},batch_id:{},loss is:{}\".format(epoch,batch_id,avg_loss.numpy()))\n",
    "            \n",
    "            # 后向传播\n",
    "            avg_loss.backward()\n",
    "            opt.step()\n",
    "            opt.clear()   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2c05e1bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 本地 jupyter 没有办法跑动\n",
    "# model = MNIST()\n",
    "# train(model)\n",
    "# paddle.save(model.state_dict(),\"./pdparams/mnist.pdparams\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51e6550a",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aed38af4",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0ef4c69",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "878694cb",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "99e24776",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82fc0727",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0cd182b5",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
